/*
 * @[H]:  Copyright (c) 2021 Phytium Information Technology, Inc. 
 * 
 *  SPDX-License-Identifier: Apache-2.0. 
 * 
 * @Date: 2021-07-19 21:48:50
 * @LastEditTime: 2021-07-23 11:40:46
 * @Description:  Description of file
 * @Modify History: 
 * * * Ver   Who        Date         Changes
 * * ----- ------     --------    --------------------------------------
 */

#ifndef DRIVERS_ETH_F_XMAC_H
#define DRIVERS_ETH_F_XMAC_H
#include "ft_types.h"
#include "ft_assert.h"
#include "f_xmac_hw.h"
#include "f_xmac_bdring.h"
#include "parameters.h"

#define FXMAC_ERR_INVALID_PARAM FT_CODE_ERR(ErrModBsp, ErrBspEth, 0x1u)
#define FXMAC_ERR_SG_LIST FT_CODE_ERR(ErrModBsp, ErrBspEth, 0x2u)
#define FXMAC_STATUS_IS_STARTED FT_CODE_ERR(StatusModBsp, ErrBspEth, 0x3u)
#define FXMAC_FAILUE FT_CODE_ERR(ErrModBsp, ErrBspEth, 0x4u)
#define FXMAC_ERR_SG_NO_LIST FT_CODE_ERR(ErrModBsp, ErrBspEth, 0x5u)
#define FXMAC_MII_BUSY FT_CODE_ERR(StatusModBsp, ErrBspEth, 0x6u)

/** @name Configuration options
 *
 * Device configuration options. See the FXMAC_SetOptions(),
 * FXMACClearOptions() and FXMAC_GetOptions() for information on how to
 * use options.
 *
 * The default state of the options are noted and are what the device and
 * driver will be set to after calling FXMAC_Reset() or
 * FXMAC_Initialize().
 *
 * @{
 */

#define FXMAC_PROMISC_OPTION 0x00000001U
/**< Accept all incoming packets.
 *   This option defaults to disabled (cleared) */

#define FXMAC_FRAME1536_OPTION 0x00000002U
/**< Frame larger than 1516 support for Tx & Rx.x
 *   This option defaults to disabled (cleared) */

#define FXMAC_VLAN_OPTION 0x00000004U
/**< VLAN Rx & Tx frame support.
 *   This option defaults to disabled (cleared) */

#define FXMAC_FLOW_CONTROL_OPTION 0x00000010U
/**< Enable recognition of flow control frames on Rx
 *   This option defaults to enabled (set) */

#define FXMAC_FCS_STRIP_OPTION 0x00000020U
/**< Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not
 *   stripped.
 *   This option defaults to enabled (set) */

#define FXMAC_FCS_INSERT_OPTION 0x00000040U
/**< Generate FCS field and add PAD automatically for outgoing frames.
 *   This option defaults to disabled (cleared) */

#define FXMAC_LENTYPE_ERR_OPTION 0x00000080U
/**< Enable Length/Type error checking for incoming frames. When this option is
 *   set, the MAC will filter frames that have a mismatched type/length field
 *   and if FXMAC_REPORT_RXERR_OPTION is set, the user is notified when these
 *   types of frames are encountered. When this option is cleared, the MAC will
 *   allow these types of frames to be received.
 *
 *   This option defaults to disabled (cleared) */

#define FXMAC_TRANSMITTER_ENABLE_OPTION 0x00000100U
/**< Enable the transmitter.
 *   This option defaults to enabled (set) */

#define FXMAC_RECEIVER_ENABLE_OPTION 0x00000200U
/**< Enable the receiver
 *   This option defaults to enabled (set) */

#define FXMAC_BROADCAST_OPTION 0x00000400U
/**< Allow reception of the broadcast address
 *   This option defaults to enabled (set) */

#define FXMAC_MULTICAST_OPTION 0x00000800U
/**< Allows reception of multicast addresses programmed into hash
 *   This option defaults to disabled (clear) */

#define FXMAC_RX_CHKSUM_ENABLE_OPTION 0x00001000U
/**< Enable the RX checksum offload
 *   This option defaults to enabled (set) */

#define FXMAC_TX_CHKSUM_ENABLE_OPTION 0x00002000U
/**< Enable the TX checksum offload
 *   This option defaults to enabled (set) */

#define FXMAC_JUMBO_ENABLE_OPTION 0x00004000U
#define FXMAC_SGMII_ENABLE_OPTION 0x00008000U

/****************************************************************************/
/**
*
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be enabled.
*
* @param instance_p is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to enable. The mask can
*        be formed using a set of bitwise or'd values.
*
* @note
* The state of the transmitter and receiver are not modified by this function.
* C-style signature
*     void FXMAC_INT_ENABLE(XEmacPs *instance_p, u32 Mask)
*
*****************************************************************************/
#define FXMAC_INT_ENABLE(instance_p, Mask)              \
    FXMAC_WRITEREG32((instance_p)->config.base_address, \
                     FXMAC_IER_OFFSET,                  \
                     ((Mask)&FXMAC_IXR_ALL_MASK));

/****************************************************************************/
/**
*
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
* each bit set to 1 in <i>Mask</i>, will be enabled.
*
* @param instance_p is a pointer to the instance to be worked on.
* @param Mask contains a bit mask of interrupts to enable. The mask can
*        be formed using a set of bitwise or'd values.
*
* @note
* The state of the transmitter and receiver are not modified by this function.
* C-style signature
*     void FXMAC_INT_Q1ENABLE(XEmacPs *instance_p, u32 Mask)
*
*****************************************************************************/
#define FXMAC_INT_Q1ENABLE(instance_p, Mask)            \
    FXMAC_WRITEREG32((instance_p)->config.base_address, \
                     FXMAC_INTQ1_IER_OFFSET,            \
                     ((Mask)&FXMAC_INTQ1_IXR_ALL_MASK));

#define FXMAC_DEFAULT_OPTIONS               \
    ((u32)FXMAC_FLOW_CONTROL_OPTION |       \
     (u32)FXMAC_FCS_INSERT_OPTION |         \
     (u32)FXMAC_FCS_STRIP_OPTION |          \
     (u32)FXMAC_BROADCAST_OPTION |          \
     (u32)FXMAC_LENTYPE_ERR_OPTION |        \
     (u32)FXMAC_TRANSMITTER_ENABLE_OPTION | \
     (u32)FXMAC_RECEIVER_ENABLE_OPTION |    \
     (u32)FXMAC_RX_CHKSUM_ENABLE_OPTION |   \
     (u32)FXMAC_TX_CHKSUM_ENABLE_OPTION)

/* The next few constants help upper layers determine the size of memory
 * pools used for Ethernet buffers and descriptor lists.
 */
#define FXMAC_MAC_ADDR_SIZE 6U /* size of Ethernet header */

#define FXMAC_MTU 1500U         /* max MTU size of Ethernet frame */
#define FXMAC_MTU_JUMBO 10240U  /* max MTU size of jumbo frame */
#define FXMAC_HDR_SIZE 14U      /* size of Ethernet header */
#define FXMAC_HDR_VLAN_SIZE 18U /* size of Ethernet header with VLAN */
#define FXMAC_TRL_SIZE 4U       /* size of Ethernet trailer (FCS) */
#define FXMAC_MAX_FRAME_SIZE (FXMAC_MTU + FXMAC_HDR_SIZE + \
                              FXMAC_TRL_SIZE)
#define FXMAC_MAX_VLAN_FRAME_SIZE (FXMAC_MTU + FXMAC_HDR_SIZE + \
                                   FXMAC_HDR_VLAN_SIZE + FXMAC_TRL_SIZE)
#define FXMAC_MAX_VLAN_FRAME_SIZE_JUMBO (FXMAC_MTU_JUMBO + FXMAC_HDR_SIZE + \
                                         FXMAC_HDR_VLAN_SIZE + FXMAC_TRL_SIZE)

/** @name Callback identifiers
 *
 * These constants are used as parameters to FXMAC_SetHandler()
 * @{
 */
#define FXMAC_HANDLER_DMASEND 1U
#define FXMAC_HANDLER_DMARECV 2U
#define FXMAC_HANDLER_ERROR 3U
/*@}*/

#define FXMAC_DMA_SG_IS_STARTED 0
#define FXMAC_DMA_SG_IS_STOPED 1

#define FXMAC_SPEED_100 0U
#define FXMAC_SPEED_1000 1U
#define FXMAC_SPEED_2500 2U
#define FXMAC_SPEED_5000 3U
#define FXMAC_SPEED_10000 4U
#define FXMAC_SPEED_25000 5U

typedef void (*FXmacIrqHandler)(void *args);
typedef void (*FXmacErrorIrqHandler)(void *args, u32 direction, u32 error_word);
/* Interface Mode definitions */
typedef enum
{
    FXMAC_PHY_INTERFACE_MODE_SGMII,
    FXMAC_PHY_INTERFACE_MODE_RMII,
    FXMAC_PHY_INTERFACE_MODE_RGMII,
    FXMAC_PHY_INTERFACE_MODE_XGMII,
    FXMAC_PHY_INTERFACE_MODE_USXGMII,
} FXmacPhyInterface;

typedef struct
{
    u32 instance_id; /* Id of device*/
    volatile uintptr_t base_address;
    FXmacPhyInterface interface;
    u32 max_queue_num; // Number of Xmac Controller Queues
    u32 tx_queue_id;   // 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number
    u32 rx_queue_id;   // 0 ~ FT_XMAC_QUEUE_MAX_NUM ,Index queue number
    u32 hotplug_irq_num;
    u32 queue_irq_num[FT_XMAC_QUEUE_MAX_NUM];

} FXmacConfig;

typedef struct
{
    u32 queue_id;
    FXmacBdRing bdring;

} FXmacQueue;

typedef struct
{

    FXmacConfig config;
    u32 is_ready; /* Device is ininitialized and ready*/
    u32 is_started;

    FXmacQueue tx_bd_queue; /* Transmit Queue */
    FXmacQueue rx_bd_queue; /* Receive Queue */

    FXmacIrqHandler send_irq_handler;
    void *send_args;

    FXmacIrqHandler recv_irq_handler;
    void *recv_args;

    FXmacErrorIrqHandler error_irq_handler;
    void *error_args;

    u32 options; /* Current options word */
    u32 rx_buf_mask;
    u32 max_mtu_size;
    u32 max_frame_size;
    u32 max_vlan_frame_size;

} FXmac;

void FXmacGetMacAddress(FXmac *instance_p, void *address_ptr, u8 index);
LONG FXmacSetMacAddress(FXmac *instance_p, void *address_ptr, u8 index);
LONG FXmacSetTypeIdCheck(FXmac *instance_p, u32 id_check, u8 Index);
LONG FXmacSetOptions(FXmac *instance_p, u32 options);
LONG FXmacClearOptions(FXmac *instance_p, u32 options);
void FXmacClearHash(FXmac *instance_p);

void FXmacStart(FXmac *instance_p);
void FXmacStop(FXmac *instance_p);
void FXmacReset(FXmac *instance_p);
LONG FXmacCfgInitialize(FXmac *instance_p, FXmacConfig *config_p);
void FXmacSetQueuePtr(FXmac *instance_p, uintptr QPtr, u8 QueueNum,
                      u16 Direction);

LONG FXmacPhyWrite(FXmac *instance_p, u32 phy_address,
                   u32 register_num, u16 phy_data);

LONG FXmacPhyRead(FXmac *instance_p, u32 phy_address,
                  u32 register_num, u16 *phydat_aptr);

#endif // !